﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using TumbaloSoft.Models;
using IBatisNet.DataMapper;
using TumbaloSoft.Helpers;
using TumbaloSoft.Helpers.QueryObjects;
using System.IO;
using System.Threading;
using iTextSharp.text;


namespace TumbaloSoft.Controllers
{
   
    public class EmpleadosController : TumbaloController 
    {
        private static Object lockObject = new Object();
        //
        // GET: /Empleados/

        public ActionResult Index(BusquedaEmpleado empleadoBuscar)
        {
            if (defaultAction != null) return defaultAction;
            //Obtener edificio
            
            int numActivos=0;
            try
            {
                int idPerfil = AccountController.getIdPerfil(HttpContext);
                if (idPerfil == 2)
                {
                    int idPersona = AccountController.getIdPersona(HttpContext);
                    AdministradorEdificios administrador = HelperAdministrador.selectByIdPersona(idPersona);
                    int idEdificio = HelperAdministrador.buscaEdificioAdministrado(administrador.prIdAdministrador);
                    Edificio edificio = HelperEdificio.selectById(idEdificio);
                    empleadoBuscar.prEdificio = edificio;
                    List<Edificio> listaEdificios = new List<Edificio>();
                    listaEdificios.Add(edificio);
                    ViewBag.listaEdificio = listaEdificios;
                    numActivos = HelperEmpleado.selectCountActivos(administrador);
                }
                else 
                { 
                    ViewBag.listaEdificio = HelperEdificio.selectAll();
                    numActivos = HelperEmpleado.selectCountActivos();
                }
                    
            ViewBag.listaTipoEmpleado = HelperTipoEmpleado.selectAll();
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al intentar cargar la lista de empleados", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            if (empleadoBuscar.prTipoEmpleado == null) 
            { 
            empleadoBuscar.prTipoEmpleado = new TipoEmpleado();
            empleadoBuscar.prTipoEmpleado.prIdTipoEmpleado=0;
            }

            if (empleadoBuscar.prEdificio == null)
            {
                empleadoBuscar.prEdificio = new Edificio();
                empleadoBuscar.prEdificio.prIdEdificio = 0;
            }
            //Fijo un rango por default de fechas que la base de datos soporte    
            if (empleadoBuscar.prFechaNacimientoMin.Year < 1900) empleadoBuscar.prFechaNacimientoMin = new DateTime(1900, 1, 1);
            if (empleadoBuscar.prFechaNacimientoMax.Year < 1900) empleadoBuscar.prFechaNacimientoMax = new DateTime(2500, 1, 1);

            try
            {
                ViewBag.listaEmpleado = HelperEmpleado.buscar(empleadoBuscar);
                
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al intentar cargar la lista de empleados", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            ViewBag.prevPage = empleadoBuscar.prPage - 1;
            ViewBag.nextPage = empleadoBuscar.prPage + 1;
            ViewBag.numPages = numActivos / empleadoBuscar.prPageSize;
            if ((numActivos % empleadoBuscar.prPageSize) > 0) ViewBag.numPages++;

            return View();
        }

        public ActionResult Registrar()
        {
            if (defaultAction != null) return defaultAction;
            try
            {
            ViewBag.listaTipoEmpleado = HelperTipoEmpleado.selectAll();
            ViewBag.listaTipo = HelperTipoDocumento.selectAll();
            ViewBag.listaDistrito = HelperDistrito.selectAll();

            //Verificar si es general o de edificios
            int idPerfil = AccountController.getIdPerfil(HttpContext);
            if (idPerfil == 2)
            {
                int idPersona = AccountController.getIdPersona(HttpContext);
                AdministradorEdificios administrador = HelperAdministrador.selectByIdPersona(idPersona);
                int idEdificio = HelperAdministrador.buscaEdificioAdministrado(administrador.prIdAdministrador);
                Edificio edificio = HelperEdificio.selectById(idEdificio);
                List<Edificio> listaEdificios = new List<Edificio>();
                listaEdificios.Add(edificio);
                ViewBag.listaEdificios=listaEdificios;
            } else  ViewBag.listaEdificios = HelperEdificio.selectAll();
            
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al intentar registrar al vendedor", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            return View();
        }

        [HttpPost]
        public ActionResult Registrar(Empleado empleado)
        {
            if (defaultAction != null) return defaultAction;
            Boolean existe;
            try
            {
                ViewBag.listaTipoEmpleado = HelperTipoEmpleado.selectAll();
                ViewBag.listaTipo = HelperTipoDocumento.selectAll();
                ViewBag.listaDistrito = HelperDistrito.selectAll();
                int idPerfil = AccountController.getIdPerfil(HttpContext);
                if (idPerfil == 2)
                {
                    int idPersona = AccountController.getIdPersona(HttpContext);
                    AdministradorEdificios administrador = HelperAdministrador.selectByIdPersona(idPersona);
                    int idEdificio = HelperAdministrador.buscaEdificioAdministrado(administrador.prIdAdministrador);
                    Edificio edificio = HelperEdificio.selectById(idEdificio);
                    List<Edificio> listaEdificios = new List<Edificio>();
                    listaEdificios.Add(edificio);
                    ViewBag.listaEdificio = listaEdificios;
                }
                else ViewBag.listaEdificio = HelperEdificio.selectAll();
                existe = HelperPersonaNatural.ExistePersona(empleado.prCodigoDocumento);
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al intentar registrar al vendedor", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
        
            //Remover dias inactivos de la validación y asignar estado
            if ("0"==empleado.prHorario.prLunes.prActivo)
            {
                empleado.prHorario.prLunes.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prLunes.prHoraEntrada");
                ModelState.Remove("prHorario.prLunes.prHoraSalida");
                ModelState.Remove("prHorario.prLunes.prHoraEntradaStr");
                ModelState.Remove("prHorario.prLunes.prHoraSalidaStr");

            }
            else empleado.prHorario.prLunes.prEstado = "ACTIVO";

            if ("0"==empleado.prHorario.prMartes.prActivo)
            {
                empleado.prHorario.prMartes.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prMartes.prHoraEntrada");
                ModelState.Remove("prHorario.prMartes.prHoraSalida");
                ModelState.Remove("prHorario.prMartes.prHoraEntradaStr");
                ModelState.Remove("prHorario.prMartes.prHoraSalidaStr");
            }
            else empleado.prHorario.prMartes.prEstado = "ACTIVO"; 

            if ("0"==empleado.prHorario.prMiercoles.prActivo)
            {
                empleado.prHorario.prMiercoles.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prMiercoles.prHoraEntrada");
                ModelState.Remove("prHorario.prMiercoles.prHoraSalida");
                ModelState.Remove("prHorario.prMiercoles.prHoraEntradaStr");
                ModelState.Remove("prHorario.prMiercoles.prHoraSalidaStr");

            }
            else empleado.prHorario.prMiercoles.prEstado = "ACTIVO"; 

            if ("0"==empleado.prHorario.prJueves.prActivo)
            {
                empleado.prHorario.prJueves.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prJueves.prHoraEntrada");
                ModelState.Remove("prHorario.prJueves.prHoraSalida");
                ModelState.Remove("prHorario.prJueves.prHoraEntradaStr");
                ModelState.Remove("prHorario.prJueves.prHoraSalidaStr");

            }
            else empleado.prHorario.prJueves.prEstado = "ACTIVO"; 

            if ("0"==empleado.prHorario.prViernes.prActivo)
            {
                empleado.prHorario.prViernes.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prViernes.prHoraEntrada");
                ModelState.Remove("prHorario.prViernes.prHoraSalida");
                ModelState.Remove("prHorario.prViernes.prHoraEntradaStr");
                ModelState.Remove("prHorario.prViernes.prHoraSalidaStr");

            }
            else empleado.prHorario.prViernes.prEstado = "ACTIVO"; 

            if ("0"==empleado.prHorario.prSabado.prActivo)
            {
                empleado.prHorario.prSabado.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prSabado.prHoraEntrada");
                ModelState.Remove("prHorario.prSabado.prHoraSalida");
                ModelState.Remove("prHorario.prSabado.prHoraEntradaStr");
                ModelState.Remove("prHorario.prSabado.prHoraSalidaStr");

            }
            else empleado.prHorario.prSabado.prEstado = "ACTIVO"; 

            if ("0"==empleado.prHorario.prDomingo.prActivo)
            {
                empleado.prHorario.prDomingo.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prDomingo.prHoraEntrada");
                ModelState.Remove("prHorario.prDomingo.prHoraSalida");
                ModelState.Remove("prHorario.prDomingo.prHoraEntradaStr");
                ModelState.Remove("prHorario.prDomingo.prHoraSalidaStr");

            }
            else empleado.prHorario.prDomingo.prEstado = "ACTIVO"; 
            //Fin Remover dias inactivos de la validación

            if (existe == true)
            {
                ModelState.AddModelError("prCodigoDocumento", "Ya existe la persona");
                return View(empleado);
            }

            if (!empleado.validarEdad())
            {
                ModelState.AddModelError("prFechaNacimiento", "La persona debe de ser mayor de edad");
                return View(empleado);
            }
            string error="";
            if (!empleado.validarHorario(ref error))
            {
                ModelState.AddModelError("prHorario", error);
                return View(empleado);
            }
            
            ModelState.Remove("prPeriodoLaboral.prEdificio.prArea");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prDireccion");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prNombre");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prNroPisos");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prMonto");

            if (ModelState.IsValid)
            {
                empleado.prEstado="ACTIVO";
                try
                {
                    lock (lockObject)
                    {
                        empleado.prIdEmpleado = (int)HelperEmpleado.SiguienteCodigo();
                        empleado.prIdPersona = (int)HelperPersonaNatural.SiguienteCodigo();
                        empleado.prPeriodoLaboral.prIdPeriodoLaboral = (int)HelperEmpleado.SiguienteCodigoPeriodoLaboral();
                        empleado.prPeriodoLaboral.prFechaCese = DateTime.MaxValue;
                        HelperEmpleado.insert(empleado);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Current.Error("Error al intentar registrar al vendedor", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }
                ViewBag.mensaje = "Se registró el empleado con éxito.";
                ViewBag.returnURL = "/Empleados/Index";
                return View("~/Views/Shared/Exito.cshtml");
            }
            else
            {
               
                return View();
            }
            
        }

        public ActionResult Modificar(int? id)
        {
            if (defaultAction != null) return defaultAction;
            try
            {
                ViewBag.listaTipoEmpleado = HelperTipoEmpleado.selectAll();
                ViewBag.listaTipo = HelperTipoDocumento.selectAll();
                ViewBag.listaDistrito = HelperDistrito.selectAll();
                //Verificar si es general o de edificios
                int idPerfil = AccountController.getIdPerfil(HttpContext);
                if (idPerfil == 2)
                {
                    int idPersona = AccountController.getIdPersona(HttpContext);
                    AdministradorEdificios administrador = HelperAdministrador.selectByIdPersona(idPersona);
                    int idEdificio = HelperAdministrador.buscaEdificioAdministrado(administrador.prIdAdministrador);
                    Edificio edificio = HelperEdificio.selectById(idEdificio);
                    List<Edificio> listaEdificios = new List<Edificio>();
                    listaEdificios.Add(edificio);
                    ViewBag.listaEdificios = listaEdificios;
                }
                else ViewBag.listaEdificios = HelperEdificio.selectAll();
            
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al modificar el empleado", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            //Si se llamo sin parametro deberia devolver error
            if (!id.HasValue) return HttpNotFound("Error con el parametro enviado.");

            Empleado empleado = HelperEmpleado.selectById(id.Value);            
            //si el empleado no se encontro se devuelve un error
            if (empleado == null) return HttpNotFound("No existe el empleado requerido");

            //Obtengo el horario
            empleado.prHorario = HelperEmpleado.selectHorarioEmpleado(empleado.prIdEmpleado);
            return View(empleado);
        }


        [HttpPost]
        public ActionResult Modificar(Empleado empleado)
        {
            if (defaultAction != null) return defaultAction;
            //Remover dias inactivos de la validación y asignar estado
            if ("0" == empleado.prHorario.prLunes.prActivo)
            {
                empleado.prHorario.prLunes.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prLunes.prHoraEntrada");
                ModelState.Remove("prHorario.prLunes.prHoraSalida");
            }
            else empleado.prHorario.prLunes.prEstado = "ACTIVO";

            if ("0" == empleado.prHorario.prMartes.prActivo)
            {
                empleado.prHorario.prMartes.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prMartes.prHoraEntrada");
                ModelState.Remove("prHorario.prMartes.prHoraSalida");
            }
            else empleado.prHorario.prMartes.prEstado = "ACTIVO";

            if ("0" == empleado.prHorario.prMiercoles.prActivo)
            {
                empleado.prHorario.prMiercoles.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prMiercoles.prHoraEntrada");
                ModelState.Remove("prHorario.prMiercoles.prHoraSalida");
            }
            else empleado.prHorario.prMiercoles.prEstado = "ACTIVO";

            if ("0" == empleado.prHorario.prJueves.prActivo)
            {
                empleado.prHorario.prJueves.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prJueves.prHoraEntrada");
                ModelState.Remove("prHorario.prJueves.prHoraSalida");

            }
            else empleado.prHorario.prJueves.prEstado = "ACTIVO";

            if ("0" == empleado.prHorario.prViernes.prActivo)
            {
                empleado.prHorario.prViernes.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prViernes.prHoraEntrada");
                ModelState.Remove("prHorario.prViernes.prHoraSalida");

            }
            else empleado.prHorario.prViernes.prEstado = "ACTIVO";

            if ("0" == empleado.prHorario.prSabado.prActivo)
            {
                empleado.prHorario.prSabado.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prSabado.prHoraEntrada");
                ModelState.Remove("prHorario.prSabado.prHoraSalida");

            }
            else empleado.prHorario.prSabado.prEstado = "ACTIVO";

            if ("0" == empleado.prHorario.prDomingo.prActivo)
            {
                empleado.prHorario.prDomingo.prEstado = "INACTIVO";
                ModelState.Remove("prHorario.prDomingo.prHoraEntrada");
                ModelState.Remove("prHorario.prDomingo.prHoraSalida");

            }
            else empleado.prHorario.prDomingo.prEstado = "ACTIVO";
            //Fin Remover dias inactivos de la validación

            try
            {
                ViewBag.listaTipoEmpleado = HelperTipoEmpleado.selectAll();
                ViewBag.listaTipo = HelperTipoDocumento.selectAll();
                ViewBag.listaDistrito = HelperDistrito.selectAll();
                int idPerfil = AccountController.getIdPerfil(HttpContext);
                if (idPerfil == 2)
                {
                    int idPersona = AccountController.getIdPersona(HttpContext);
                    AdministradorEdificios administrador = HelperAdministrador.selectByIdPersona(idPersona);
                    int idEdificio = HelperAdministrador.buscaEdificioAdministrado(administrador.prIdAdministrador);
                    Edificio edificio = HelperEdificio.selectById(idEdificio);
                    List<Edificio> listaEdificios = new List<Edificio>();
                    listaEdificios.Add(edificio);
                    ViewBag.listaEdificio = listaEdificios;
                }
                else ViewBag.listaEdificio = HelperEdificio.selectAll();
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al modificar el empleado", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            if (!empleado.validarEdad())
            {
                ModelState.AddModelError("prFechaNacimiento", "La persona debe de ser mayor de edad.");
                return View(empleado);
            }

            if (empleado.prPeriodoLaboral.prFechaCese == null) { empleado.prPeriodoLaboral.prFechaCese = DateTime.MaxValue; }
           
            ModelState.Remove("prPeriodoLaboral.prEdificio.prArea");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prDireccion");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prNombre");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prNroPisos");
            ModelState.Remove("prPeriodoLaboral.prEdificio.prMonto");
            ModelState.Remove("prPeriodoLaboral.prFechaCese");
            ModelState.Remove("prHorario");
            if (ModelState.IsValid)
            {
                try
                {
                    HelperEmpleado.update(empleado);
                    ViewBag.mensaje = "Se modificó el empleado con éxito.";
                    ViewBag.returnURL = "/Empleados/Index";
                    return View("~/Views/Shared/Exito.cshtml");
                }
                catch (Exception ex)
                {
                    Logger.Current.Error("Error al modificar el empleado", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }
            }

            return View(empleado);
        }

        public ActionResult Eliminar(int? id)
        {
            if (defaultAction != null) return defaultAction;
            try
            {
                ViewBag.listaTipoEmpleado = HelperTipoEmpleado.selectAll();
                ViewBag.listaTipo = HelperTipoDocumento.selectAll();
                ViewBag.listaDistrito = HelperDistrito.selectAll();
                ViewBag.listaEdificios = HelperEdificio.selectAll();
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al eliminar el empleado", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
            //Si se llamo sin parametro deberia devolver error
            if (!id.HasValue) return HttpNotFound("Error con el parametro enviado.");
                Empleado empleado;
                try
                {
                    empleado= HelperEmpleado.selectById(id.Value);
                }
                catch (Exception ex)
                {
                    Logger.Current.Error("Error al eliminar el empleado", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }

            //si el empleado no se encontro se devuelve un error
            if (empleado == null) return HttpNotFound("No existe el empleado requerido");
            return View(empleado);
        }

        [HttpPost]
        public ActionResult Eliminar(Empleado empleado)
        {
            if (defaultAction != null) return defaultAction;
            try
            {
                ViewBag.listaTipoEmpleado = HelperTipoEmpleado.selectAll();
                ViewBag.listaTipo = HelperTipoDocumento.selectAll();
                ViewBag.listaDistrito = HelperDistrito.selectAll();
                ViewBag.listaEdificios = HelperEdificio.selectAll();
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al eliminar el empleado", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

            if (empleado!=null&&empleado.prIdEmpleado!=0)
            {
                try
                {
                    HelperEmpleado.delete(empleado);
                    ViewBag.mensaje = "Se eliminó el empleado con éxito.";
                    ViewBag.returnURL = "/Empleados/Index";
                    return View("~/Views/Shared/Exito.cshtml");
                }
                catch (Exception ex)
                {
                    Logger.Current.Error("Error al eliminar el empleado", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }
                
            }

            return View(empleado);
        }

        public ActionResult RegistrarEntrada()
        {
            if (defaultAction != null) return defaultAction;
            try
            {
                return View();
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al registrar la entrada del empleado", ex);
                return View("~/Views/Shared/Error.cshtml");
            }
        }

        [HttpPost]
        public ActionResult RegistrarEntrada(Empleado empleado)
        {
            if (defaultAction != null) return defaultAction;
            if (empleado.prIdEmpleado != 0 && empleado != null )
            {

                
                int idSelect = empleado.prIdEmpleado;

                try
                {
                    empleado = HelperEmpleado.selectById(idSelect);
                    if (empleado == null)
                    {
                        ModelState.AddModelError("prIdEmpleado", "El codigo ingresado no corresponde a ningun empleado.");
                        return View(empleado);
                    }

                    if (HelperEmpleado.verificarEntrada(empleado.prIdEmpleado))
                    {
                        ModelState.AddModelError("prIdEmpleado", "Usted ya registro su entrada.");
                        return View(empleado);                       
                    }
                    HelperEmpleado.RegistrarEntrada(empleado.prIdEmpleado);
                }
                catch (Exception ex)
                {
                    Logger.Current.Error("Error al registrar la entrada del empleado", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }           
            }
            ViewBag.mensaje = "Usted registró su entrada con éxito.";
            ViewBag.returnURL = "/Empleados/RegistrarEntrada";
            return View("~/Views/Shared/Exito.cshtml");
            
        }

        public ActionResult RegistrarSalida()
        {
            if (defaultAction != null) return defaultAction;
            try
            {

                return View();
            }
            catch (Exception ex)
            {
                Logger.Current.Error("Error al registrar la entrada del empleado", ex);
                return View("~/Views/Shared/Error.cshtml");
            }

        }

        [HttpPost]
        public ActionResult RegistrarSalida(Empleado empleado)
        {
            if (defaultAction != null) return defaultAction;
            if (empleado.prIdEmpleado != 0 && empleado != null)
            {
                try
                {
                    int idSelect = empleado.prIdEmpleado;
                    empleado = HelperEmpleado.selectById(idSelect);
                    if (empleado == null)
                    {
                        ModelState.AddModelError("prIdEmpleado", "El codigo ingresado no corresponde a ningun empleado.");
                        return View(empleado);
                    }

                    if (!HelperEmpleado.verificarEntrada(empleado.prIdEmpleado))
                    {
                        ModelState.AddModelError("prIdEmpleado", "Usted no registro su entrada.");
                        return View(empleado);
                    }

                    if (!HelperEmpleado.verificarSalida(empleado.prIdEmpleado))
                    {
                        ModelState.AddModelError("prIdEmpleado", "Usted ya registro su Salida.");
                        return View(empleado);
                    }
               
                    HelperEmpleado.RegistrarSalida(empleado.prIdEmpleado);
                }
                catch (Exception ex)
                {
                    Logger.Current.Error("Error al registrar la salida del empleado", ex);
                    return View("~/Views/Shared/Error.cshtml");
                }

            }
            ViewBag.mensaje = "Usted registró su salida con éxito.";
            ViewBag.returnURL = "/Empleados/RegistrarSalida";
            return View("~/Views/Shared/Exito.cshtml");
        }

    }
}
